#include <cppunit/config/SourcePrefix.h>
#include "TestAST.h"
#include <string>

void TestAST::setUp() {
}

void TestAST::tearDown() {
}

CPPUNIT_TEST_SUITE_REGISTRATION( TestAST );

void TestAST::testConstructor(){
	Node procNode(new Procedure(0));
	AST ast1 = AST();
	AST ast2(&procNode);

	CPPUNIT_ASSERT_EQUAL_MESSAGE("AST constructed without root node (default constructor)", (Node*)0, ast1.getRoot());
	CPPUNIT_ASSERT_EQUAL_MESSAGE("AST constructed with a root node", &procNode, ast2.getRoot());
}

void TestAST::testSetGetRoot(){
	Node plusNode(new Plus(), 1);
	Node variableNode(new Variable(0), 1);
	AST ast1 = AST();
	ast1.setRoot(&plusNode);
	AST ast2(&variableNode);

	CPPUNIT_ASSERT_EQUAL_MESSAGE("AST with correct root node (1)", &plusNode, ast1.getRoot());
	CPPUNIT_ASSERT_EQUAL_MESSAGE("AST with correct root node (2)", &variableNode, ast2.getRoot());
}

void TestAST::testGetSubTree(){
	/* var1 = var2 + const */
	Node assignNode(new Assign(), 1);
	assignNode.setNodeID(0);
	Node variableNode1(new Variable(0), 1);
	variableNode1.setNodeID(1);
	Node plusNode(new Plus(), 1);
	plusNode.setNodeID(2);
	Node variableNode2(new Variable(1), 1);
	variableNode2.setNodeID(3);
	Node constantNode(new Constant(10), 1);
	constantNode.setNodeID(4);

	assignNode.addChildNode(&variableNode1);
	assignNode.addChildNode(&plusNode);
	plusNode.addChildNode(&variableNode2);
	plusNode.addChildNode(&constantNode);
	AST ast1(&assignNode);

	CPPUNIT_ASSERT_EQUAL_MESSAGE("Assign node with ID 0", 0, assignNode.getNodeID());
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Variable node1 with ID 1", 1, variableNode1.getNodeID());
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Plus node with ID 2", 2, plusNode.getNodeID());
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Variable node2 with ID 3", 3, variableNode2.getNodeID());
	CPPUNIT_ASSERT_EQUAL_MESSAGE("Constant node with ID 4", 4, constantNode.getNodeID());

	int plusNodeID = plusNode.getNodeID();
	int constantNodeID = constantNode.getNodeID();

	AST ast2 = ast1.getSubTree(plusNodeID);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("AST with correct root node (3)", &plusNode, ast2.getRoot());
	AST ast3 = ast2.getSubTree(constantNodeID);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("AST with correct root node (4)", &constantNode, ast3.getRoot());
}